<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import wjfwService from '@/api/wjfw'
import { applyFpscOutputDTO } from '@/api/wjfw-dto'

const emit = defineEmits(['getWjbh'])
// 文件大小限制，超过切片
const sliceSize = 1024 * 1024 * 1

const fpwjObj = ref<applyFpscOutputDTO>({
  fpwjbh: '',
  fpdx: 0,
})

/**
 * 上传按钮
 * @param multiple 是否多个上传
 * @param fileType 文件类型
 * @param size 文件最大尺寸允许上传
 */
const upload = (multiple = false, fileType: string, size?: number) => {
  // 创建上传input
  const dom = document.createElement('input')
  dom.type = 'file'
  if (fileType) {
    dom.accept = fileType
  }
  dom.multiple = multiple
  dom.click()

  // dom上传事件
  dom.onchange = (e: any) => {
    const file = e.target.files[0]
    dom.value = ''
    // TODO 只做单文件上传，多文件后续
    // 文件类型验证
    if (fileType && !fileType.includes(file.type)) {
      ElMessage.warning('上传格式错误')
      return
    }
    // 文件大小验证
    if (size && file.size > size) {
      ElMessage.warning('超过上传尺寸')
      return
    }
    // 判断是否切片
    if (file.size > sliceSize) {
      // 切片
      uploadSlice(file)
    } else {
      uploadNormal(file)
    }
  }
}

/* 切片上传 */
const uploadSlice = (file: File) => {
  // 先调用申请分片接口
  const params = {
    wjzdx: file.size,
    wjmc: file.name,
    md5: '',
  }
  wjfwService
    .applyFpsc(params)
    .then((res) => {
      fpwjObj.value = res.data as unknown as applyFpscOutputDTO
      // 调用执行分片功能
      excuteFpsc(file, 0)
    })
    .catch((err) => {
      !err.isError && ElMessage({ type: 'warning', message: err.message })
    })
}

/* 执行分片 */

const excuteFpsc = (file: File, index: number) => {
  // 递归调用，接口成功才继续执行
  const start = index * fpwjObj.value.fpdx
  const end = Math.min(start + fpwjObj.value.fpdx, file.size)
  const blobSlice = file.slice(start, end)
  if (index < Math.ceil(file.size / fpwjObj.value.fpdx)) {
    const formData = new FormData()
    formData.append('file', blobSlice)
    formData.append('fpwjbh', fpwjObj.value.fpwjbh)
    formData.append('fph', index + '')
    wjfwService
      .excuteFpsc(formData)
      .then(() => {
        // 分片上传成功再继续下一个分片
        excuteFpsc(file, index + 1)
      })
      .catch((err) => {
        !err.isError && ElMessage({ type: 'warning', message: err.message })
      })
  } else {
    // 调用确认分片上传
    const params = {
      fpwjbh: fpwjObj.value.fpwjbh,
    }
    wjfwService
      .confirmFpsc(params)
      .then((res) => {
        emit('getWjbh', res.data.wjbh, file)
      })
      .catch((err) => {
        !err.isError && ElMessage({ type: 'warning', message: err.message })
      })
  }
}

/* 正常上传 */
const uploadNormal = (file: File) => {
  // 上传
  const formData = new FormData()
  formData.append('file', file)
  formData.append('wjmc', file.name)
  wjfwService
    .upload(formData)
    .then((res) => {
      emit('getWjbh', res.data.wjbh, file)
    })
    .catch((err) => {
      !err.isError && ElMessage({ type: 'warning', message: err.message })
    })
}

defineExpose({ upload })
</script>
<template>
  <div></div>
</template>
<style lang="scss" scoped></style>
